package com.ning.ems.service.impl;

import com.ning.ems.dao.PackageDao;
import com.ning.ems.dao.PackageStateInfoDao;
import com.ning.ems.dao.UserDao;
import com.ning.ems.dto.PSIListDto;
import com.ning.ems.entity.Package;
import com.ning.ems.entity.PackageStateInfo;
import com.ning.ems.exception.ServiceException;
import com.ning.ems.service.PackageStateInfoService;
import com.ning.ems.vo.PSIVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

import static com.ning.ems.util.Util.mapping;

/**
 * @author Ning 242741154@qq.com
 * @date 2020/4/11 23:43
 */
@Service
public class PackageStateInfoServiceImpl implements PackageStateInfoService {
    private final UserDao userDao;
    private final PackageDao packageDao;
    private final PackageStateInfoDao packageStateInfoDao;

    private final RedisTemplate<String, Serializable> redisTemplate;

    public PackageStateInfoServiceImpl(PackageDao packageDao, PackageStateInfoDao packageStateInfoDao, UserDao userDao, RedisTemplate<String, Serializable> redisTemplate) {
        this.packageDao = packageDao;
        this.packageStateInfoDao = packageStateInfoDao;
        this.userDao = userDao;
        this.redisTemplate = redisTemplate;
    }

    private PSIVo toVo(PackageStateInfo psi) {
        String courier = userDao.get(psi.getCourier(), null).getName();
        return new PSIVo(psi.getId(), psi.getPkg(), psi.getDate(),
                courier, psi.getState());
    }

    @Override
    public List<PSIVo> list(Integer pkg) {
        return mapping(packageStateInfoDao.listOfPkg(pkg), this::toVo);
    }

    @Override
    public List<PackageStateInfo> list(PSIListDto info) {
        final Integer courier = info.getCourier();
        final Integer year = info.getYear();
        final Integer month = info.getMonth();
        final Integer page = info.getPage();
        final Integer pageSize = info.getPageSize();
        final LocalDateTime startTime = LocalDateTime.of(year, month,
                0, 0, 0);
        final LocalDateTime endTime = startTime.plusMonths(1);
        final int offset = (page - 1) * pageSize;
        return packageStateInfoDao
                .listOfCourier(courier,
                        startTime, endTime,
                        offset, pageSize);
    }

    @Override
    public PackageStateInfo get(Integer id) {
        return packageStateInfoDao.get(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PackageStateInfo add(PackageStateInfo info) {
        final Integer pkgId = info.getPkg();
        final Package pkg = packageDao.get(pkgId);
        if (pkg == null) {
            throw new ServiceException("请求错误, 请刷新!");
        }
        final int newState = Math.min(pkg.getCurrState(), 4) + 1;
        info.setState(newState);
        packageStateInfoDao.add(info);
        // 修改对应包裹的最新状态
        packageDao.updateState(pkgId, newState);
        redisTemplate.delete("pkg::id-" + pkgId);
        return info;
    }

    @Override
    public boolean deleteById(Integer id) {
        final PackageStateInfo info = get(id);
        if (info == null) {
            return false;
        }
        final Integer pkgId = info.getPkg();
        final Integer state = info.getState();
        final Package pkg = packageDao.get(pkgId);
        if (!state.equals(pkg.getCurrState())) {
            return false;
        }
        int rtn = packageStateInfoDao.deleteById(id);
        return rtn == 1;
    }

    @Override
    public boolean deleteByPkg(Integer pkgId) {
        final Package pkg = packageDao.get(pkgId);
        if (pkg == null) {
            int rtn = packageStateInfoDao.deleteByPkg(pkgId);
            return rtn == 1;
        }
        return false;
    }
}
